home *** CD-ROM | disk | FTP | other *** search
- /* Gravis Ultrasound MIDI port test program */
- /* Copyright 1993 Dave Perry */
- /* This program may be used for non-commercial purposes only */
-
- #include <dos.h>
- #include <stdio.h>
- #include <conio.h>
- #include <stdlib.h>
-
- #pragma inline
-
- #define CONTROL 0x100 /* Control port offset */
- #define DATA 0x101 /* Data port offset */
- #define BUFSIZE 512 /* Ring buffer */
- #define PIC_MASK 0x21 /* 8259 interrupt mask port */
- #define PIC_MASK2 0xa1 /* Secondary 8259 mask port */
-
-
- unsigned char buffer[BUFSIZE];
- unsigned char *head = buffer;
- unsigned char *tail = buffer;
-
- unsigned int base; /* Card base address */
-
- void interrupt ( *old_isr)(...);
-
- /*
- status byte meaning data bytes
-
- 0x80-0x8f note off 2 - 1 byte pitch, followed by 1 byte velocity
- 0x90-0x9f note on 2 - 1 byte pitch, followed by 1 byte velocity
- 0xa0-0xaf key pressure 2 - 1 byte pitch, 1 byte pressure (after-touch)
- 0xb0-0xbf parameter 2 - 1 byte parameter number, 1 byte setting
- 0xc0-0xcf program 1 byte program selected
- 0xd0-0xdf chan. pressure 1 byte channel pressure (after-touch)
- 0xe0-0xef pitch wheel 2 bytes gives a 14 bit value, least significant
- 7 bits first
- */
-
- enum status_t {UNKNOWN = 0,
- NOTE_OFF = 0x80,
- NOTE_ON = 0x90,
- KEY_PRES = 0xa0,
- PARM = 0xb0,
- PROGRAM = 0xc0,
- CHAN_PRES= 0xd0,
- PITCH = 0xe0,
- SYSEX = 0xf0};
-
- char *keyname[] = {
- "C ",
- "C# ",
- "D ",
- "D# ",
- "E ",
- "F ",
- "F# ",
- "G ",
- "G# ",
- "A ",
- "A# ",
- "B "
- };
-
-
- void decode(unsigned char *message)
- {
-
- printf("| ");
- if((message[0] & 0xf0) != SYSEX)
- printf("Ch.%-2d ",(message[0] & 0x0f) + 1);
- switch(message[0] & 0xf0){
- case UNKNOWN:
- printf("Unknown message");
- break;
- case NOTE_OFF:
- printf("Note Off %d%s Vel: %d",
- message[1]/12,keyname[message[1] % 12],message[2]);
- break;
- case NOTE_ON:
- printf("Note On %d%s Vel: %d",
- message[1]/12,keyname[message[1] % 12],message[2]);
- break;
- case KEY_PRES:
- printf("Key Pres. %d%s Pressure: %d",
- message[1]/12,keyname[message[1] % 12],message[2]);
- break;
- case PARM:
- printf("Parameter %d Setting: %d",message[1],message[2]);
- break;
- case PROGRAM:
- printf("Program %d",message[1]);
- break;
- case CHAN_PRES:
- printf("Ch Press. %d",message[1]);
- break;
- case PITCH:
- printf("P. Wheel %d",(message[1]+(message[2] << 7)) - 8192);
- break;
- case SYSEX:
- printf("System");
- break;
- default:
- ;
- }
- }
-
- void
- showbyte(unsigned char abyte)
- {
- static status_t cur_status = UNKNOWN;
- static int arg_cnt = 0;
- static unsigned char message[3];
-
- if(abyte & 0x80) { /* It's a status byte */
- if((abyte < 0xf8)){ /* Ignore "real time" bytes */
- printf("\n%2x ",abyte); /* Start new line, print status byte */
- cur_status = (status_t)(abyte & 0xf0);
- message[0] = abyte;
- arg_cnt = 0;
- }
- } else { /* Not a status byte */
- switch(cur_status) {
- case UNKNOWN:
- case NOTE_OFF:
- case NOTE_ON:
- case KEY_PRES:
- case PARM:
- case PITCH:
- case SYSEX:
- if((++arg_cnt % 2) && (arg_cnt != 1))
- printf("\n %02x ",abyte);
- else
- printf("%02x ",abyte);
- if((arg_cnt + 1) % 2) {
- message[2] = abyte;
- decode(message);
- } else
- message[1] = abyte;
-
-
- break;
- case PROGRAM:
- case CHAN_PRES:
- if(arg_cnt++)
- printf("\n %02x ");
- else
- printf("%02x ",abyte);
- message[1] = abyte;
- decode(message);
- break;
- } /* switch */
- } /* else */
- }
-
- void
- send_eoi()
- {
- asm mov al,0bh; /* read in-service register from */
- asm out 0a0h,al; /* secondary 8259 */
- asm nop; /* settling delay */
- asm nop
- asm nop
- asm in al,0a0h; /* get it */
- asm or al,al; /* Any bits set? */
- asm jz lab1; /* nope, not a secondary interrupt */
- asm mov al,20h; /* Get EOI instruction */
- asm out 0a0h,al; /* Secondary 8259 */
- lab1: asm mov al,20h; /* 8259 end-of-interrupt command */
- asm out 20h,al; /* Primary 8259 */
- }
-
-
- /* MIDI input interrupt handler */
- void interrupt
- midi_isr(...)
- {
- static cnt = 0;
-
- *head = inportb(base+DATA); /* Grab the data */
- asm cli;
- if(cnt == BUFSIZE - 1) {/* Adjust the buffer pointer */
- cnt = 0;
- head = buffer;
- } else {
- ++head;
- ++cnt;
- }
- asm sti;
- send_eoi();
- }
-
- /* Pull a byte from the buffer */
- unsigned char
- pullbyte(void)
- {
- static cnt = 0;
- unsigned char retval;
-
- asm cli; /* Ints off for pointer manipulation */
- if (head != tail)
- {
- retval = *tail++;
- cnt++;
- if(cnt == BUFSIZE) {
- cnt = 0;
- tail = buffer;
- }
- }
- asm sti;
- return(retval);
- }
-
- void
- hook_irq(unsigned char irq)
- {
- unsigned char abyte,int_mask,vector;
- unsigned int pic_mask; /* Address of PIC mask */
-
- if(irq < 8){
- vector = irq + 8;
- pic_mask = PIC_MASK;
- int_mask = 1 << irq;
- }
- else {
- vector = irq + 0x70 - 8;
- pic_mask = PIC_MASK2;
- int_mask = 1 << (irq - 8);
- }
-
-
- /* save the existing interrupt vector */
- old_isr = getvect(vector);
-
- /* Install our interrupt vector */
- setvect(vector,midi_isr);
-
- /* Enable interrupts on the MIDI UART */
- outportb(base+CONTROL,0x95);
-
- /* Set up the 8259 PIC chip */
- abyte = inportb(pic_mask); /* Read 8259 mask */
- abyte &= ~int_mask; /* Clear mask for desired IRQ */
- outportb(pic_mask,abyte);
-
- }
-
- void
- unhook_irq(unsigned char irq)
- {
-
- unsigned char abyte, int_mask, vector;
- unsigned int pic_mask;
-
- if(irq < 8){
- vector = irq + 8;
- pic_mask = PIC_MASK;
- int_mask = 1 << irq;
- }
- else {
- vector = irq + 0x70 - 8;
- pic_mask = PIC_MASK2;
- int_mask = 1 << (irq - 8);
- }
-
- /* Mask the interrupt we hooked */
- abyte = inportb(pic_mask); /* Read 8259 mask */
- abyte |= int_mask; /* Set mask for desired IRQ */
- outportb(pic_mask,abyte);
-
- /* Restore old interrupt handler */
- setvect(vector,midi_isr);
- }
-
- main()
- {
- int abyte;
- char *envstring;
- unsigned int midi_irq,dummy;
-
- envstring = getenv("ULTRASND");
- if(envstring == NULL) {
- printf("ULTRASND environment string not found\n");
- printf("Check your Ultrasound setup\n");
- exit(0);
- }
- sscanf(envstring,"%x,%d,%d,%d,%d",
- &base,&dummy,&dummy,&dummy,&midi_irq);
-
- hook_irq(midi_irq);
-
- printf("\nGravis Ultrasound MIDI Tester V1.0");
- printf("\nCopyright 1993 Dave Perry");
-
- printf("\nYour current setup is Base = %x, MIDI IRQ = %d",base,midi_irq);
- printf("\nReading MIDI input - press any key to exit\n");
-
- while (!kbhit()){
- if(head != tail) { /* If new byte available */
- abyte = pullbyte();
-
- /* MIDI Thru */
- while(!(inportb(base+CONTROL) & 0x02))
- ;
- outportb(base+DATA,abyte);
-
- showbyte(abyte);
-
- }
- }
- printf("\n");
-
- unhook_irq(midi_irq);
- return 0;
- }
-